home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !preview / c / main < prev    next >
Encoding:
Text File  |  1990-07-27  |  17.0 KB  |  620 lines

  1. /* main.c --- main of Preview.  */
  2.  
  3. #include "d2rd.h"
  4. #include "menus.h"
  5. #include <stdarg.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "output.h"
  10. #include "kernel.h"
  11. #include "template.h"
  12. #include "resspr.h"
  13. #include "res.h"
  14. #include "font.h"
  15. #include "bbc.h"
  16. #include "colourtran.h"
  17. #include "flex.h"
  18. #include "visdelay.h"
  19.  
  20. struct dvi_file *dvi_files = NULL;
  21. struct display *windows;
  22.  
  23. os_error *err;
  24. wimp_i iconbar_icon;
  25. wimp_w proginfo, saveas;
  26.  
  27.  
  28. /* The filetype of the file to be saved.  This is set according to the icon
  29.    type of the user_drag from the saveas window.  */
  30.  
  31. int saveas_filetype;
  32.  
  33.  
  34. /* The buffer where the input of the SAVEAS_FILENAME icon is put.  */
  35.  
  36. char *saveas_buffer;
  37.  
  38.  
  39. /* The MY_REF field as put in the message header by the wimp when sending the
  40.    DATASAVE message.  */
  41.  
  42. int msg_ref;
  43.  
  44.  
  45. /* To keep things extremely simple, all windows display a sprite which has
  46.    the same mode as the current screenmode.  Hence, on a mode-change every
  47.    sprite needs to be redefined.  And we always need to know the current mode.  */
  48.  
  49. int vdu_mode;
  50.  
  51. /* Record where the menu was opened, so it can be used to influence the
  52.    reopening of a window after choosing a new magnification.  */
  53.  
  54. wimp_mousestr menu_pos;
  55.  
  56. /* To have ourselves in the executable image.  */
  57.  
  58. char copyright_notice[] =
  59. "This is !Preview\nCopyright 1990 Graham Toal and Pieter Schoenmakers\n";
  60.  
  61.  
  62. /* This function is called at exit.  */
  63.  
  64. void
  65. cleanup (void)
  66. {
  67.   if (loading_a_file)
  68.     visdelay_end ();
  69.   wimp_taskclose (wimpt_task ());
  70. }
  71.  
  72.  
  73.  
  74. void
  75. set_saveas_state (char *file_name, char *sprite_name)
  76. {
  77.   wimp_icreate ic;
  78.   int i;
  79.  
  80.   /* Change the file icon.  */
  81.  
  82.   wimpt_noerr (wimp_get_icon_info (saveas, SAVEAS_FILEICON, &ic.i));
  83.   ic.i.flags = wimp_ISPRITE | wimp_IHCENTRE | wimp_IVCENTRE | wimp_INDIRECT | (6 << 12);
  84.   ic.i.data.indirectsprite.name = sprite_name;
  85.   ic.i.data.indirectsprite.spritearea = (void *) 1;
  86.   ic.i.data.indirectsprite.nameisname = TRUE;
  87.   ic.w = saveas;
  88.   wimpt_noerr (wimp_delete_icon (saveas, SAVEAS_FILEICON));
  89.   wimpt_noerr (wimp_create_icon (&ic, &i));
  90.   if (i != SAVEAS_FILEICON)
  91.     tfatal ("xfer_send template mangled");
  92.  
  93.   /* Change the file name.  */
  94.  
  95.   wimpt_noerr (wimp_get_icon_info (saveas, SAVEAS_FILENAME, &ic.i));
  96.   saveas_buffer = ic.i.data.indirecttext.buffer;
  97.   strcpy (saveas_buffer, file_name);
  98. }
  99.  
  100.  
  101.  
  102. void
  103. initialise (void)
  104. {
  105.   char fname[1024];   /* YECH! */
  106.   wimp_icreate ic;
  107.   wimp_i dum;
  108.  
  109.   wimpt_init (PROGRAM_NAME);
  110.   atexit (cleanup);
  111.  
  112.   res_init ("Preview");
  113.   resspr_init ();
  114.   res_findname ("Templates", fname);
  115.   template_init ();
  116.   template_readfile (fname);
  117.   visdelay_init ();
  118. #ifdef USE_FLEX
  119.   flex_init ();
  120. #endif
  121.  
  122.   vdu_mode = (_kernel_osbyte (135, 0, 0) >> 8) & 0xff;
  123.  
  124.   /* prefetch the aboutbox and saveas windows.  */
  125.  
  126.   wimpt_noerr (wimp_create_wind (template_syshandle ("progInfo"), &proginfo));
  127.   wimpt_noerr (wimp_create_wind (template_syshandle ("xfer_send"), &saveas));
  128.  
  129.   /* Record where the saveas window puts the filename.  */
  130.  
  131.   wimpt_noerr (wimp_get_icon_info (saveas, SAVEAS_FILENAME, &ic.i));
  132.   saveas_buffer = ic.i.data.indirecttext.buffer;
  133.  
  134.   /* Our IconBar icon. */
  135.  
  136.   ic.w = -1;
  137.   ic.i.box.x0 = 0;
  138.   ic.i.box.y0 = 0;
  139.   ic.i.box.x1 = 68;
  140.   ic.i.box.y1 = 68;
  141.   ic.i.flags = wimp_ISPRITE | wimp_INDIRECT | (3 << 12);
  142.   ic.i.data.indirectsprite.name = "!Preview";
  143.   ic.i.data.indirectsprite.spritearea = resspr_area ();
  144.   ic.i.data.indirectsprite.nameisname = 5;
  145.   wimpt_noerr (wimp_create_icon (&ic, &iconbar_icon));
  146.  
  147.   /* Put the VERSION_STRING information in the aboutbox.  */
  148.  
  149.   ic.w = proginfo;
  150.   ic.i.box.x0 = 154;
  151.   ic.i.box.y0 = -208;
  152.   ic.i.box.x1 = 630;
  153.   ic.i.box.y1 = -160;
  154.   ic.i.flags = wimp_ITEXT | wimp_INDIRECT | wimp_IBORDER | wimp_IFILLED | wimp_IHCENTRE | wimp_IVCENTRE | (7 << 24);
  155.   ic.i.data.indirecttext.buffer = version_string;
  156.   ic.i.data.indirecttext.validstring = "";
  157.   ic.i.data.indirecttext.bufflen = strlen (version_string) + 1;
  158.   wimpt_noerr (wimp_create_icon (&ic, &dum));
  159.  
  160.   iconbar_menu = menu_syshandle (menu_new (PROGRAM_NAME, ">Info,Quit"));
  161.   mag_menu = menu_new ("", "\\magstep0,\\magstephalf,\\magstep1,\\magstep2,\\magstep3,\\magstep4,\\magstep5,75dpi tweak");
  162.   saveas_menu = menu_new ("", ">Sprite,>Drawfile");
  163.   goto_page = menu_new ("", "42424242");
  164.   menu_make_writeable (goto_page, 1, goto_page_buffer, 12, "a0-9");
  165.   window_menu = menu_new (PROGRAM_NAME, "Next,Previous,Goto page,Magnification,New view|Save|Close,Quit");
  166.   menu_submenu (window_menu, 1 + MAINMENU_GOTO_PAGE, goto_page);
  167.   menu_submenu (window_menu, 1 + MAINMENU_MAGNIFICATION, mag_menu);
  168.   menu_submenu (window_menu, 1 + MAINMENU_SAVEAS, saveas_menu);
  169.  
  170.   x_os_scale = 1 << bbc_vduvar (bbc_XEigFactor);
  171.   y_os_scale = 1 << bbc_vduvar (bbc_YEigFactor);
  172. } /* initialise */
  173.  
  174.  
  175.  
  176. void
  177. redraw_window(struct display *w)
  178. {
  179.   int more;
  180.   double xs, ys;
  181.   int x, y;
  182.   wimp_redrawstr r;
  183.  
  184.   r.w = w->w_handle;
  185.   wimp_redraw_wind (&r, &more);
  186.  
  187.   factors (w, &xs, &ys);
  188.   font_converttoos( (int)(w->hor_offset * xs), 0, &x, &y );
  189.   while (more)
  190.     {
  191.       wimpt_noerr (sprite_put_given (w->area, &w->sid, 0,
  192.                                      r.box.x0 - r.scx + x,
  193.                                      r.box.y1 - r.scy + y));
  194.       wimp_get_rectangle (&r, &more);
  195.     }
  196. }
  197.  
  198.  
  199. void
  200. close_window (wimp_w wh)
  201. {
  202.   struct display *w;
  203.  
  204.   for (w = windows; w; w = w->next)
  205.     if (w->w_handle == wh)
  206.       break;
  207.  
  208.   if (w == NULL)
  209.     return;
  210.  
  211.   if (! w->file->complete)
  212.     {
  213.       fatal ("Cannot delete a file while still loading it (sorry).");
  214.       return;
  215.     }
  216.  
  217.   wimp_close_wind (wh);
  218.   wimp_delete_wind (wh);
  219.  
  220.   do_a_poll ();
  221.  
  222.   visdelay_begin ();
  223.   delete_display (wh);
  224.   visdelay_end ();
  225. }
  226.  
  227.  
  228. int
  229. main (int argc, char *argv[])
  230. {
  231.   int i;
  232.  
  233.   initialise ();
  234.  
  235.   for (i = 1; i < argc; i++)
  236.     read_a_file (argv[i]);
  237.  
  238.   for (;;)
  239.     do_a_poll ();
  240.  
  241.   exit (0);        /* Calls cleanup ().  */
  242.   return (0);      /* To keep stupid compiler happy.  */
  243. } /* main */
  244.  
  245.  
  246. /* Handle any pending events.  If LOADING_A_FILE is TRUE, return when the
  247.    NULL event is encountered, otherwise never return.  */
  248.  
  249. void
  250. do_a_poll (void)
  251. {
  252.   wimp_eventstr b;
  253.   wimp_msgstr msg;
  254.   wimp_mousestr mstr;
  255.   struct display *w;
  256.   int event;
  257.  
  258.   do
  259.     {
  260.       if (loading_a_file)
  261.         wimpt_noerr (wimp_poll (0, &b));
  262.       else
  263.         wimpt_noerr (wimp_pollidle (0, &b, 0));
  264.  
  265.       event = b.e;
  266.  
  267.       switch (event)
  268.         {
  269.         case wimp_EREDRAW:
  270.           for (w = windows; w; w = w->next)
  271.             if (w->w_handle == b.data.o.w)
  272.               break;
  273.           if (w)
  274.             redraw_window (w);
  275.  
  276.           break;
  277.  
  278.         case wimp_EOPEN:
  279.           wimp_open_wind (&b.data.o);
  280.           break;
  281.  
  282.         case wimp_ECLOSE:
  283.           close_window (b.data.o.w);
  284.           break;
  285.  
  286.         case wimp_EBUT:
  287.           handle_buttons (&b.data);
  288.           break;
  289.  
  290.         case wimp_EUSERDRAG:
  291.           {
  292.             char *s;
  293.             _kernel_swi_regs r;
  294.  
  295.             wimpt_noerr (wimp_get_point_info (&mstr));
  296.             msg.hdr.size = sizeof (wimp_msgstr);
  297.             msg.hdr.your_ref = 0;
  298.             msg.hdr.action = wimp_MDATASAVE;
  299.             msg.data.datasave.w = mstr.w;
  300.             msg.data.datasave.i = mstr.i;
  301.             msg.data.datasave.x = mstr.x;
  302.             msg.data.datasave.y = mstr.y;
  303.             msg.data.datasave.estsize = (saveas_filetype == 0xff9 ? 4 + flex_size ((flex_ptr) &which_menu->area)
  304.                                                                   : (54 * which_menu->page->text_max + 68 * which_menu->page->rule_max
  305.                                                                      + which_menu->page->char_max + 40));
  306.             msg.data.datasave.type = saveas_filetype;
  307.             s = strrchr (saveas_buffer, '.');
  308.             if (s == NULL)
  309.               s = saveas_buffer;
  310.  
  311.             if (strlen (s) > 11)
  312.               {
  313.                 fatal ("Bad filename");
  314.                 break;
  315.               }
  316.             strcpy (&msg.data.datasave.leaf[0], s);
  317.  
  318.             r.r[0] = wimp_ESENDWANTACK;
  319.             r.r[1] = (int) &msg;
  320.             r.r[2] = mstr.w;
  321.             r.r[3] = mstr.i;
  322.             _kernel_swi (0x400e7, &r, &r);
  323.  
  324.             msg_ref = msg.hdr.my_ref;
  325. #if 0       /* Do not delete the menu yet!  */
  326.             wimp_create_menu ((wimp_menustr *) -1, 0, 0);
  327. #endif
  328.           }
  329.  
  330.           break;
  331.  
  332.         case wimp_EMENU:
  333.           if (which_menu == NULL)
  334.             {
  335.               /* Something was selected from the iconbar menu.  */
  336.  
  337.               switch (b.data.menu[0])
  338.                 {
  339.                 case ICONBARMENU_QUIT:
  340.                   exit (0);
  341.                 default:
  342.                   break;
  343.                 }
  344.             }
  345.           else
  346.             {
  347.               wimp_redrawstr r;
  348.  
  349.               w = which_menu;
  350.               switch (b.data.menu[0])
  351.                 {
  352.                 case MAINMENU_NEXT:
  353.                   do_a_poll ();
  354.  
  355.                   w->page = w->page->next;
  356.                   if (w->page == NULL)
  357.                     w->page = w->file->pages;
  358.  
  359.                   set_window_title (w);
  360.                   fill_sprite (w);
  361.  
  362.                   r.w = w->w_handle;
  363.                   r.box.x0 = 0;
  364.                   r.box.y0 = 0;
  365.                   r.box.x1 = 1000000000;
  366.                   r.box.y1 = 1000000000;
  367.                   wimp_force_redraw (&r);
  368.  
  369.                   break;
  370.  
  371.                 case MAINMENU_PREVIOUS:
  372.                   {
  373.                     struct page *p = w->file->pages;
  374.  
  375.                     do_a_poll ();
  376.  
  377.                     while (p->next && p->next != w->page)
  378.                       p = p->next;
  379.                     w->page = p;
  380.  
  381.                     set_window_title (w);
  382.                     fill_sprite (w);
  383.  
  384.                     r.w = w->w_handle;
  385.                     r.box.x0 = 0;
  386.                     r.box.y0 = 0;
  387.                     r.box.x1 = 1000000000;
  388.                     r.box.y1 = 1000000000;
  389.                     wimp_force_redraw (&r);
  390.                   }
  391.  
  392.                   break;
  393.  
  394.                 case MAINMENU_GOTO_PAGE:
  395.                   {
  396.                     int i;
  397.                     struct page *p;
  398.  
  399.                     if (b.data.menu[1] == -1)
  400.                       break;
  401.  
  402.                     i = atoi (goto_page_buffer);
  403.                     if (i == 0)
  404.                       break;
  405.  
  406.                     for (p = w->file->pages; p; p = p->next)
  407.                       if (p->dvi_page == i)
  408.                         break;
  409.  
  410.                     if (p == NULL || p->complete == FALSE)
  411.                       {
  412.                         if (loading_a_file && current_dvi_file == w->file)
  413.                           fatal ("Page does not exist or has not been loaded yet.");
  414.                         else
  415.                           fatal ("Page does not exist.");
  416.                         break;
  417.                       }
  418.                     if (p == w->page)
  419.                       {
  420.                         fatal ("Page is already being displayed.");
  421.                         break;
  422.                       }
  423.  
  424.                     w->page = p;
  425.                     set_window_title (w);
  426.  
  427.                     fill_sprite (w);
  428.  
  429.                     r.w = w->w_handle;
  430.                     r.box.x0 = 0;
  431.                     r.box.y0 = 0;
  432.                     r.box.x1 = 1000000000;
  433.                     r.box.y1 = 1000000000;
  434.                     wimp_force_redraw (&r);
  435.  
  436.                     break;
  437.                   }
  438.                 case MAINMENU_MAGNIFICATION:
  439.                   {
  440.                     wimp_winfo wi;
  441.  
  442.                     if (b.data.menu[1] == -1 || b.data.menu[1] == w->magstep)
  443.                       break;
  444.  
  445.                     wi.w = w->w_handle;
  446.                     wimp_get_wind_info (&wi);
  447.  
  448.                     do_a_poll ();
  449.  
  450.                     if (b.data.menu[1] == 7 /* 75dpi tweak */) {
  451.                        if (w->mag_tweak == 1.0) w->mag_tweak = 75.0/90.0;
  452.                                            else w->mag_tweak = 1.0;
  453.                     } else /* magstep selection */ {
  454.                        w->magstep = b.data.menu[1];
  455.                     }
  456.  
  457. #ifdef USE_FLEX
  458.                     flex_free ((flex_ptr) &w->area);
  459. #else
  460.                     free (w->area);
  461.                     w->area = 0;
  462. #endif
  463.                     define_sprite (w);
  464.                     fill_sprite (w);
  465.                     adjust_window_size (w);
  466.  
  467.                     break;
  468.                   }
  469.  
  470.                 case MAINMENU_CLONE:
  471.                   build_a_window (which_menu->file, which_menu->page);
  472.                   break;
  473.  
  474.                 case MAINMENU_CLOSE:
  475.                   close_window (w->w_handle);
  476.                   break;
  477.  
  478.                 case MAINMENU_QUIT:
  479.                   exit (0);
  480.                   break;
  481.  
  482.                 default:
  483.                   break;
  484.                 }
  485.             }
  486.           break;
  487.  
  488.         case wimp_ESCROLL:
  489.           if (ABS (b.data.scroll.x) == 2)
  490.             b.data.scroll.o.x += SGN (b.data.scroll.x) * (b.data.scroll.o.box.x1 - b.data.scroll.o.box.x0);
  491.           else if (ABS (b.data.scroll.x) == 1)
  492.             b.data.scroll.o.x += SGN (b.data.scroll.x) * 32;
  493.  
  494.           if (ABS (b.data.scroll.y) == 2)
  495.             b.data.scroll.o.y += SGN (b.data.scroll.y) * (b.data.scroll.o.box.y1 - b.data.scroll.o.box.y0);
  496.           else if (ABS (b.data.scroll.y) == 1)
  497.             b.data.scroll.o.y += SGN (b.data.scroll.y) * 32;
  498.  
  499.           wimp_open_wind (&b.data.scroll.o);
  500.           break;
  501.  
  502.         case wimp_ESEND:
  503.         case wimp_ESENDWANTACK:
  504.           switch (b.data.msg.hdr.action)
  505.             {
  506.             case wimp_MCLOSEDOWN:
  507.               exit (0);
  508.               break;
  509.  
  510.             case wimp_MDATASAVEOK:
  511.               if (b.data.msg.hdr.your_ref == msg_ref)
  512.                 {
  513.                   output_saveas (b.data.msg.data.datasaveok.name);
  514.                   wimp_create_menu ((wimp_menustr *) -1, 0, 0);
  515.  
  516.                   msg.hdr.size = sizeof (wimp_msgstr);
  517.                   msg.hdr.your_ref = 0;
  518.                   msg.hdr.action = wimp_MDATALOAD;
  519.                   msg.data.dataload.w = mstr.w;
  520.                   msg.data.dataload.i = mstr.i;
  521.                   msg.data.dataload.x = mstr.x;
  522.                   msg.data.dataload.y = mstr.y;
  523.                   msg.data.dataload.size = 0;
  524.                   msg.data.dataload.type = saveas_filetype;
  525.                   strcpy (msg.data.dataload.name, b.data.msg.data.datasaveok.name);
  526.                   wimpt_noerr (wimp_sendmessage (wimp_ESENDWANTACK, &msg, (wimp_t) mstr.w));
  527.                 }
  528.               break;
  529.  
  530.             case wimp_MMENUWARN:
  531.               if (which_menu == 0)
  532.                 {
  533.                   if (b.data.msg.data.words[3] == 0)
  534.                     wimpt_complain (wimp_create_submenu ((wimp_menustr *) proginfo, b.data.msg.data.words[1], b.data.msg.data.words[2]));
  535.                 }
  536.               else if (b.data.msg.data.words[3] == MAINMENU_SAVEAS)
  537.                 {
  538.                   if (b.data.msg.data.words[4] == SAVEASMENU_PAINT)
  539.                     {
  540.                       saveas_filetype = 0xff9;
  541.                       set_saveas_state ("Sprite", "file_ff9");
  542.                     }
  543.                   else
  544.                     {
  545.                       saveas_filetype = 0xaff;
  546.                       set_saveas_state ("DrawFile", "file_aff");
  547.                     }
  548.                   wimpt_complain (wimp_create_submenu ((wimp_menustr *) saveas, b.data.msg.data.words[1], b.data.msg.data.words[2]));
  549.                 }
  550.                 
  551.               break;
  552.  
  553.             case wimp_MMODECHANGE:
  554.               {
  555.                 int i = (_kernel_osbyte (135, 0, 0) >> 8) & 0xff;
  556.                 struct display *w;
  557.  
  558.                 if (vdu_mode == i)
  559.                   break;
  560.  
  561.                 vdu_mode = i;
  562.  
  563.                 for (w = windows; w; w = w->next)
  564.                   {
  565. #ifdef USE_FLEX
  566.                     flex_free ((flex_ptr) &w->area);
  567. #else
  568.                     free (w->area);
  569.                     w->area = 0;
  570. #endif
  571.                     define_sprite (w);
  572.                     fill_sprite (w);
  573.                     adjust_window_size (w);
  574.                   }
  575.               }
  576.               break;
  577.  
  578.             case wimp_MDATALOAD:
  579.               if (b.data.msg.data.dataload.w == -2 && b.data.msg.data.dataload.i == iconbar_icon)
  580.                 {
  581.                   read_a_file (b.data.msg.data.dataload.name);
  582.  
  583.                   b.data.msg.hdr.your_ref = b.data.msg.hdr.my_ref;
  584.                   b.data.msg.hdr.action = wimp_MDATALOADOK;
  585.                   wimp_sendmessage (wimp_ESEND, &b.data.msg, b.data.msg.hdr.task);
  586.                 }
  587.               break;
  588.  
  589.             case wimp_MDATAOPEN:
  590.               if (b.data.msg.data.dataopen.type == FILE_TYPE_DVI)
  591.                 {
  592.                   b.data.msg.hdr.your_ref = b.data.msg.hdr.my_ref;
  593.                   wimp_sendmessage (wimp_EACK, &b.data.msg, b.data.msg.hdr.task);
  594.                   read_a_file (b.data.msg.data.dataopen.name);
  595.                 }
  596.               break;
  597.  
  598.             case wimp_MRAMFETCH:
  599.               wimp_create_menu ((wimp_menustr *) -1, 0, 0);
  600.               output_send (&b.data.msg);
  601.               break;
  602.  
  603.             default:
  604.               break;
  605.             }
  606.           break;
  607.  
  608.         case wimp_EACK:
  609. #if 0
  610.           fatal ("/usr/msg/ack");
  611. #endif
  612.           break;
  613.  
  614.         default:
  615.           break;
  616.         }
  617.     }
  618.   while (event);
  619. } /* do_a_poll */
  620.